﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using LJTest.entity;
using System.Data.SQLite;

//---------------------------------------------------------------------------------//

//--------------------------------产生失效预取数据集算法--------------------------//

//---------------------------------------------------------------------------------//


namespace LJTest
{
    class invalidprefetch
    {
        String InLine;
        ArrayList total = new ArrayList();
        ArrayList sub = new ArrayList();
        public invalidprefetch()
        {
            readRules2();
            //readFrequency();
        }


        /* **
         * 读取关联规则文件
         * 
         * 第二类关联规则，类似0.833333333333333|15->9
         ** */
        private void readRules2()
        {
            if (File.Exists(Common.RULE_FILE_PATH))
            {
                try
                {
                    //String InLine;
                    //ArrayList total = new ArrayList();
                    //ArrayList sub = new ArrayList();

                    using (StreamReader sr = new StreamReader(Common.RULE_FILE_PATH, Encoding.GetEncoding("gb2312")))
                    {
                        while ((InLine = sr.ReadLine()) != null)
                        {
                            double mf = 0;
                            int firstIndex = InLine.IndexOf("|->");
                            if (firstIndex <= 0)
                            {
                                int indexSeperator = InLine.IndexOf("|");
                                mf = Convert.ToDouble(InLine.Substring(0,indexSeperator));
                                string substring = InLine.Substring(indexSeperator+1);
                                int indexArrow = substring.IndexOf("->");
                                sub.Add(substring.Substring(0, indexArrow)); //箭头前面的一个数字
                                string str = substring.Substring(indexArrow + 2, substring.Length - 2 - indexArrow);
                                 foreach (string k in str.Split(','))
                                 {
                                     sub.Add(k);
                                 }
                                 total.Add(new Rule(mf, sub));
                                 sub = new ArrayList();
                            }

                           
                        }
                    }

                   
                }
                catch (Exception ex)
                {
                    Console.WriteLine("读取关联规则中的记录出错：" + ex.Message);

                }
            }

        }

        //事务中某个数据项失效时获得的预取集合

        public static double cacheSize;
        public static double cacheDataNUM;
        public static void invalidpre(ArrayList notincache)
        {
            int nn ,mm;
            double t = 0.1, tt = 0.1;
            ArrayList ip = new ArrayList();
            invalidprefetch ivp = new invalidprefetch();
            //失效的数据项
            //先比较失效事务数据项与读取的TOTAL中的第一个数是否匹配？是，则取出total中的该规则中的所有数据放到失效预预取数据集IP'中
            foreach (string invalid in notincache)
            {
                ip.Add(invalid);
                ArrayList ruleList = new ArrayList();
                double maxMf = 0;
                foreach (Rule myrule in ivp.total)
                {
                    
                    ArrayList sub = myrule.rule;
                    string first =(string) sub[0];
                    if (invalid.Equals(first))
                    {
                        if (myrule.mf > maxMf) maxMf = myrule.mf;
                        ruleList.Add(myrule);
                    }
                    
                }
               
                foreach (Rule entity in ruleList)
                {
                    for (int i = 1; i < entity.rule.Count; i++)
                    {
                        if (!ip.Contains(entity.rule[i])) ip.Add(entity.rule[i]);
                    }
                }

            }
           
            mm = ip.Count;
            Common.totalenergy1 -= mm*t;
            Console.WriteLine("CMIP数据预取策略失效请求的数据集中数目为：{0}", mm);
            Console.WriteLine("CMIP数据预取策略剩余的电能为：{0}", Common.totalenergy1);
            //再比较IP'中的数据与缓存中的数据是否存在相同？相同：则删除；不相同：什么都不做
            ArrayList cache = Common.readCacheFromDB(Common.CACHE_TABLE);
            //ArrayList cacheTemp = Common.readCacheFromDB(Common.CACHE_TEMP_TABLE);
            ArrayList ipClone = (ArrayList)ip.Clone();
            foreach (string str in ipClone)
            {
                foreach (Cache s in cache)
                {
                    if (s.data.CompareTo(str)==0)
                    {
                        ip.Remove(str);
                    }
                }
                //foreach (Cache ss in cacheTemp)
                //{
                //    if (ss.data.CompareTo(str) == 0)
                //    {
                //        ip.Remove(str);
                //    }
                //}
            }
            nn = ip.Count;
            Common.totalenergy2 -= nn * tt;
            Console.WriteLine("Value_Based CMIP数据预取策略失效请求的数据集中数目为：{0}", nn);
            Console.WriteLine("Value_Based CMIP数据预取策略剩余的电能为：{0}", Common.totalenergy2);
             //最后得到的数据就为失效预取数据集IP
             //统计IP中的数据个数

            //将ip 中的数据写入缓存中（cache_temp),先判断缓存是否已经满了
            foreach (string str in ip)
            {
                ////ArrayList cachelist = Common.readCacheDataFromDB(Common.CACHE_TABLE);
                
                //double total = getCacheDbSize();
                
                ////ArrayList total = new ArrayList();
                //if (!Common.checkInCache(str)) 
                //{
                //    if (total + Common.CaculateDataSize(str) <= cacheSize) //还有空间可写
                //    {

                        
                //            string sql = "insert into cache values('" + DateTime.Now.ToString("s") + "' ,'" + DateTime.Now.ToString("s") + "','" + str + "','" + Common.CaculateDataSize(str) + "','" + "Y" + "')";
                //            SQLiteHelper.ExecuteSql(sql);
                //            Console.WriteLine("成功写入本次失效数据");
                       
                //    }
                //    else  //空间不足，移除旧的
                //    {
                //        string sql = "delete from cache where data in(select data from cache order by  updatetime1,updatetime2 asc limit 1)";
                //        while ((getCacheDbSize() + Common.CaculateDataSize(str)) > cacheSize)
                //        {
                //            SQLiteHelper.ExecuteSql(sql);
                //        }
                //        sql = "insert into cache values('" + DateTime.Now.ToString("s") + "' ,'" + DateTime.Now.ToString("s") + "','" + str + "','" + Common.CaculateDataSize(str) + "','" + "Y" + "')";
                //        SQLiteHelper.ExecuteSql(sql);
                //        Console.WriteLine("删除数据后，成功写入本次失效数据");

                //    }

                int total=getCacheDataNUM();
                if (!Common.checkInCache(str))
                {
                    if ( ++ total<= cacheDataNUM) //还有空间可写
                    {


                        string sql = "insert into cache values('" + DateTime.Now.ToString("s") + "' ,'" + DateTime.Now.ToString("s") + "','" + str + "','" + Common.CaculateDataSize(str) + "','" + "Y" + "')";
                        SQLiteHelper.ExecuteSql(sql);
                        Console.WriteLine("成功写入本次失效数据");

                    }
                    else  //空间不足，移除旧的
                    {
                        string sql = "delete from cache where data in(select data from cache order by  updatetime1,updatetime2 asc limit 1)";
                        SQLiteHelper.ExecuteSql(sql);
                        sql = "insert into cache values('" + DateTime.Now.ToString("s") + "' ,'" + DateTime.Now.ToString("s") + "','" + str + "','" + Common.CaculateDataSize(str) + "','" + "Y" + "')";
                        SQLiteHelper.ExecuteSql(sql);
                        Console.WriteLine("删除数据后，成功写入本次失效数据");

                    }

                }

            }
                
          

        }

        public static double getCacheDbSize()
        {
            double total = 0.0;
            string sql1 = "select case when sum(size) is null then 0 else sum(size) end as total from cache ";
            try
            {
                SQLiteDataReader reader = SQLiteHelper.ExecuteReader(sql1);
                if (reader.HasRows)
                {
                    reader.Read();
                    total = reader.GetDouble(0);

                }
                reader.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("读数据库出错" + ex.Message);
            } 
            return total;
        }


        public static int getCacheDataNUM()
        {
            int total = 0;
            string sql = "select case when count(data) is null then 0 else count(data) end as total from cache";
            try
            {
                SQLiteDataReader reader = SQLiteHelper.ExecuteReader(sql);
                if (reader.HasRows)
                {
                    reader.Read();
                    total = reader.GetInt32(0);

                }
                reader.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("读数据库出错" + ex.Message);
            }
            return total;
        }

    }
}
